package Model;

import Controller.UserManager;
import Controller.LogManager;
import java.io.IOException;
import java.net.InetAddress;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.sql.Timestamp;
import java.util.Date;
import java.util.logging.FileHandler;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.net.InetAddress;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.sql.Timestamp;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

/**
 *
 * @author pauld
 */
@WebServlet(name = "login", urlPatterns = {"/login"})
public class login extends HttpServlet{
    private HttpSession session = null;
    private static String username = null;
    private static String password = null;

    protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException, NoSuchAlgorithmException {
        response.setContentType("text/html;charset=UTF-8");
        
        String ipAdd = null;
        String origSession = null;
        MessageDigest md = MessageDigest.getInstance("SHA-256");
        session = request.getSession();
        
        int loginResult = UserManager.login(username, password);
        
        if( loginResult == 1 ){//if log in is successfull
            String name = UserManager.name;  //username of the logged in user
            String user = Integer.toString( UserManager.user );  //user id of the logged in user
            
            session.invalidate(); // invalidate existing session after authenticating user
            session = request.getSession(true); //create new session
            
            //hash the ip and session id of the user
            origSession = session.getId();  //get new session id of the user
            ipAdd = request.getRemoteAddr().concat(origSession); //get ip add of the user and concatenate with the original session id
            md.update( ipAdd.getBytes("UTF-8") );
            byte[] raw = md.digest();
            md.reset();
            
            //convert the raw hash to hex
            StringBuilder sb = new StringBuilder();
            for (byte b : raw) {
                sb.append(String.format("%02X ", b));
            }
            String newDigest = sb.toString();
            
            //set the session variables
            session.setAttribute( "sessionToken", newDigest); //store the hased value in the session variable
            session.setAttribute( "name", name );
            session.setAttribute( "user", user );

            session.setAttribute( "buy-product", "");
            session.setMaxInactiveInterval(20*60); //set idle tome to 20 minutes
            
            LogManager.logEvent("Login." + Thread.currentThread().getStackTrace()[1].getMethodName(), Level.INFO, "Successful Login", request.getRemoteAddr(), username);
            
            response.sendRedirect("index.jsp");
        }
        else if( loginResult == 0 ){//if user is locked out
            LogManager.logEvent("Login." + Thread.currentThread().getStackTrace()[1].getMethodName(), Level.INFO, "User Locked Out", request.getRemoteAddr(), username);
            response.sendRedirect("login.jsp?login=1");
        }
        else if( loginResult == -1 ){//if log in is not successful 
            LogManager.logEvent("Login." + Thread.currentThread().getStackTrace()[1].getMethodName(), Level.WARNING, "Unsuccessful Login - Wrong Credentials - " + username, request.getRemoteAddr(), "Not logged in");
            response.sendRedirect("login.jsp?login=2");
        }
    }    

    public static boolean checkInputs(HttpServletRequest request){
        username = request.getParameter("username");
        password = request.getParameter("password");
        
        //check form inputs, thorught regex, if the
        //inputs only contains alphanumeric characters
        String regexAlpaNum = "^[A-Za-z0-9]+$"; //whitelist
        Pattern pAlpaNum = Pattern.compile(regexAlpaNum, Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
        Matcher mUser = pAlpaNum.matcher(username),
                mPW = pAlpaNum.matcher(password);
        boolean resultUser = mUser.find(),
                resultPW = mPW.find();
        
        if( username.length() <= 25 &&
                password.length() <= 25 &&
                resultUser &&
                resultPW ){
            return true;
        }
        else {            
            LogManager.logEvent("Login." + Thread.currentThread().getStackTrace()[1].getMethodName(), Level.WARNING, "Unsuccessful Login - Invalid Input", request.getRemoteAddr(), "Not logged in");
            return false;
        }
    }    
    
    /*public static HttpSession getSession(){
        
        return request.getSession();
    }*/
    
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        if( checkInputs(request) ){
            try {
                processRequest(request, response);
            } catch (NoSuchAlgorithmException ex) {
                Logger.getLogger(login.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        else{
            response.sendRedirect("login.jsp?login=2");
        }
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        if( checkInputs(request) ){
            try {
                processRequest(request, response);
            } catch (NoSuchAlgorithmException ex) {
                Logger.getLogger(login.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        else{
            response.sendRedirect("login.jsp?login=2");
        }
    }

    @Override
    public String getServletInfo() {
        return "Short description";
    }
}
